home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / gfx / board / rtgmv13.lha / devdocs / tcpsrc.c < prev   
C/C++ Source or Header  |  1996-06-27  |  7KB  |  289 lines

  1. /*
  2.  
  3.    This is the source code of the TCP/IP Support stuff
  4.    of rtgmaster.library... originally it was included,
  5.    as in rtgmaster.library V5 TCP/IP Support had to
  6.    contain a LOT of Forbid()/Permit() calls, that slowed
  7.    the thing down. (This was only needed for AmiTCP stuff
  8.    inside a Shared Library). In the meanwhile, i got
  9.    a reply from the coders of AmiTCP how to do this
  10.    inside a shared library without a single Forbid()/Permit()
  11.    call... so you could call this source obsolete...
  12.    if you want to know how TCP/IP works NATIVE, you
  13.    still can have a look at it :)  Of course this source
  14.    is only usable from C, while the rtgmaster stuff is
  15.    usable from ASM, too... i hope i did not forget
  16.    any includes for the source version...
  17.  
  18.    THIS STUFF IS OBSOLETE, AS THE PROBLEMS THAT I HAD
  19.    WITH TCP/IP SUPPORT AT THE BEGINNING, DISAPPEARED...
  20.    IT IS THE CODE OF rtgmaster.library V6, AND DOES
  21.    NOT SUPPORT UDP, CONTRARY TO rtgmaster.library V7 !!!
  22.  
  23. */
  24.  
  25.  
  26. // NOTE : Function Parameters are nearly the same, only
  27. // that you have to provide a struct Library *SocketBase,
  28. // and have to call SocketBase=OpenLibrary("bsdsocket.library",4);
  29. // instead of providing SocketBase as parameters...
  30.  
  31. // Urgent note : If you want to use this code from different
  32. // TASKS, provide the SocketBase as additional parameter "SBase" and
  33. // give each function a local variable
  34. // struct Library *SocketBase=SBase;
  35. // Else you will get a LOT of AmiTCP error messages (this is the
  36. // "famous" rtgmaster V6 speedfix. At the beginning i had a
  37. // Forbid();/* Global */ SocketBase=SBase;Permit(); which
  38. // of course is much slower than the local variable stuff...
  39.  
  40. #include <sys/types.h>
  41. #include <exec/nodes.h>
  42. #include <clib/socket_protos.h>
  43. #include <pragmas/socket_pragmas.h>
  44. #include <clib/netlib_protos.h>
  45. #include <netinet/in.h>
  46. #include <netdb.h>
  47. #include <sys/ioctl.h>
  48. #include <rtgmaster/rtgTCPIP.h>
  49. #include <stdlib.h>
  50. #include <stdio.h>
  51. #include <clib/alib_protos.h>
  52. #include <exec/memory.h>
  53. #include <string.h>
  54. #include <ctype.h>
  55.  
  56. // Note : Some of these includes might ACTUALLY
  57. // be not needed... i hope i forgot no include :)
  58.  
  59. #define CREATE(result, type, number)  do {\
  60.         if (!((result) = (type *) calloc ((number), sizeof(type))))\
  61.          result=0;} while(0);
  62.  
  63. struct RTG_Socket *OpenServer(int port, int mode, int protocol)
  64. {
  65.  int opt,s;
  66.  long handle;
  67.  struct sockaddr_in sa;
  68.  static struct RTG_Socket  rs;
  69.  if ((s=socket(AF_INET,mode,protocol))<0) return(0);
  70. #if defined(SO_SNDBUF)
  71.   opt = (LARGE_BUFSIZE + GARBAGE_SPACE);
  72.   if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &opt, sizeof(opt)) < 0) return(0);
  73. #endif
  74.  
  75. #if defined(SO_REUSEADDR)
  76.   opt = 1;
  77.   if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)) < 0) return(0);
  78. #endif
  79.  
  80. #if defined(SO_LINGER)
  81.   {
  82.     struct linger ld;
  83.  
  84.     ld.l_onoff = 0;
  85.     ld.l_linger = 0;
  86.     if (setsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &ld, sizeof(ld)) < 0) return(0);
  87.   }
  88. #endif
  89.  
  90.  sa.sin_family = AF_INET;
  91.  sa.sin_port = htons(port);
  92.  sa.sin_addr.s_addr = htonl(INADDR_ANY);
  93.  if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0)
  94.   {
  95.     CloseSocket(s);
  96.     return(0);
  97.   }
  98.  listen(s,5);
  99.  rs.s=s;
  100.  rs.num=1;
  101.  rs.list=0;
  102.  FD_ZERO(&(rs.input_set));
  103.  FD_ZERO(&(rs.output_set));
  104.  FD_ZERO(&(rs.exc_set));
  105.  return(&rs);
  106. }
  107.  
  108. void makeservaddr(struct sockaddr_in *address, char *host, int port);
  109. void makeservaddr(struct sockaddr_in *address, char *host, int port)
  110. {
  111.  struct hostent *hi;
  112.  address->sin_family=AF_INET;
  113.  hi=gethostbyname(host);
  114.  bcopy(hi->h_addr,&address->sin_addr,hi->h_length);
  115.  address->sin_port=port;
  116. }
  117.  
  118. struct RTG_Socket *OpenClient(char *host, int port, int mode, int protocol)
  119. {
  120.  struct sockaddr_in sa;
  121.  struct sockaddr_in *sb;
  122.  struct hostent *hi;
  123.  long handle;
  124.  static struct RTG_Socket rs;
  125.  int s;
  126.  if ((s=socket(AF_INET,mode,protocol))<0) return(0);
  127.  makeservaddr(&sa,host,port);
  128.  if (connect(s,&sa,sizeof(sa))<0) return(0);
  129.  rs.s=s;
  130.  rs.num=1;
  131.  rs.list=0;
  132.  return(&rs);
  133. }
  134.  
  135. struct RTG_Socket *RunServer(struct RTG_Socket *s, struct RTG_Buff *in_buffer, struct RTG_Buff *out_buffer, int maxplayers)
  136. {
  137.  int maxdesc;
  138.  int num=0;
  139.  struct timeval null_time;
  140.  struct RTG_Socket *d;
  141.  int socknum=0;
  142.  struct RTG_Socket *new_conn=0;
  143.  if (maxplayers>12) maxplayers=12;
  144.  null_time.tv_sec=0;
  145.  null_time.tv_usec=0;
  146.  if (s->list==0)
  147.  {
  148.   FD_ZERO(&(s->input_set));
  149.   FD_SET(s->s,&(s->input_set));
  150.   if (WaitSelect((s->s)+1, &(s->input_set), (fd_set *) 0, (fd_set *) 0, NULL,0) >= 0)
  151.   {
  152.    // New connection...
  153.   }
  154.  }
  155.  FD_ZERO(&(s->input_set));
  156.  FD_ZERO(&(s->output_set));
  157.  FD_ZERO(&(s->exc_set));
  158.  FD_SET(s->s,&(s->input_set));
  159.  maxdesc=s->s;
  160.  if (s->list!=0) for (d=s->list;d;d=d->list)
  161.  {
  162.   if ((d->s)>maxdesc) maxdesc=d->s;
  163.   FD_SET(d->s,&(s->input_set));
  164.   FD_SET(d->s,&(s->output_set));
  165.   FD_SET(d->s,&(s->exc_set));
  166.  }
  167.  if (WaitSelect(maxdesc+1,&(s->input_set),&(s->output_set),&(s->exc_set),&null_time,0) >= 0)
  168.  {
  169.   // We have input...
  170.  }
  171.  if (FD_ISSET(s->s,&(s->input_set)))
  172.  {
  173.   // Allocate new descriptor
  174.   int i;
  175.   struct sockaddr_in peer;
  176.   int desc;
  177.   if ((desc = accept(s->s, 0,0))==-1)
  178.   {
  179.    return(0);
  180.   }
  181.   else
  182.   {
  183.    for (d=s->list;d;d=d->list)
  184.     socknum++;
  185.    if (socknum>=maxplayers)
  186.    {
  187.     CloseSocket(desc);
  188.     return(0);
  189.    }
  190.    if (s->list!=0) for(d=s->list;(d->list);d=d->list);
  191.    else d=s;
  192.    if (s->num==maxplayers) return(0);
  193.    CREATE(d->list,struct RTG_Socket,1);
  194.    if ((d->list)==0) return(0);
  195.    d=d->list;
  196.    d->s=desc;
  197.    d->num=1;
  198.    d->list=0;
  199.    new_conn=d;
  200.    s->num++;
  201.   }
  202.  }
  203.  if (s->list!=0) for (d=s->list;d;d=d->list)
  204.  {
  205.   if (FD_ISSET(d->s,&(s->exc_set)))
  206.   {
  207.    FD_CLR(d->s,&(s->input_set));
  208.    FD_CLR(d->s,&(s->output_set));
  209.    CloseSocket(d->s);
  210.   }
  211.  }
  212.  if (s->list!=0) for (d=s->list;d;d=d->list)
  213.  {
  214.   if (FD_ISSET(d->s,&(s->input_set)))
  215.   {
  216.  
  217.    int state;
  218.    state=recv(d->s,in_buffer->sock[num],in_buffer->in_size,0);
  219.    in_buffer->num[num]=d->s;
  220.    num++;
  221.    if (state<0) {num--;CloseSocket(d->s);in_buffer->num[num]=-1;}
  222.    //Handle input, if it fails, CloseSocket !!!
  223.    }
  224.  }
  225.  if (s->list!=0) for (d=s->list;d;d=d->list)
  226.  {
  227.   if (FD_ISSET(d->s,&(s->output_set)))
  228.   {
  229.    int state,f,g;
  230.    g=-1;
  231.    for (f=0;((f<maxplayers)&&(g==-1));f++)
  232.     if (out_buffer->num[f]==d->s) g=f;
  233.    state=send(d->s,&(out_buffer->sock[g]),out_buffer->out_size,0);
  234.    if (state<0) CloseSocket(d->s);
  235.    // Handle output, if it fails, CloseSocket !!!
  236.   }
  237.  }
  238.  return(new_conn);
  239. }
  240.  
  241. void CloseServer(struct RTG_Socket *s)
  242. {
  243.  if (s->s) CloseSocket(s->s);
  244.  s->s=0;
  245. }
  246.  
  247. void CloseClient(struct RTG_Socket *s)
  248. {
  249.  if (s->s) CloseSocket(s->s);
  250.  s->s=0;
  251. }
  252.  
  253. int RtgSend(struct RTG_Socket *s, char *message, int len)
  254. {
  255.  
  256.  int test;
  257.  test=(send(s->s,message,len,0));
  258.  return(test);
  259. }
  260.  
  261. int RtgRecv(struct RTG_Socket *s, char *message, int len)
  262. {
  263.  int test;
  264.  test=(recv(s->s,message,len,0));
  265.  return(test);
  266. }
  267.  
  268. struct RTG_Socket *RtgAccept(struct RTG_Socket *s)
  269. {
  270.  static struct RTG_Socket rs;
  271.  rs.s=accept(s->s,0,0);
  272.  if (rs.s>=0)
  273.  {
  274.   rs.num=1;
  275.   rs.list=0;
  276.   return(&rs);
  277.  }
  278.  else return(0);
  279. }
  280.  
  281. int RtgIoctl(struct RTG_Socket *s, long *arg)
  282. {
  283.  int test;
  284.  test=(IoctlSocket(s->s,FIONBIO,arg));
  285.  return(test);
  286. }
  287.  
  288.  
  289.